#include "tcpserverform.h"
#include "ui_tcpserverform.h"

#include <QNetworkInterface>


TcpServerForm::TcpServerForm(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::TcpServerForm)
    , m_server(nullptr)
    , m_socket(nullptr)
{
    ui->setupUi(this);

    ui->lineEdit_client_ip->setEnabled(false);
    ui->lineEdit_client_port->setEnabled(false);

    connect(ui->pushButton_listen, &QPushButton::clicked, this, &TcpServerForm::slot_listen);
    connect(ui->pushButton_disconnect, &QPushButton::clicked, this, &TcpServerForm::slot_disconnect);

    auto localAddress = [=](){

        QList<QHostAddress> list =QNetworkInterface::allAddresses();
        foreach (QHostAddress address, list)
        {
            if(address.protocol() ==QTcpSocket::IPv4Protocol)
            {
                ui->comboBox_local_ip->addItem(address.toString());
            }
        }
    };
    localAddress();
}

TcpServerForm::~TcpServerForm()
{
    delete ui;
}


void TcpServerForm::Send(const stParameter& parameter)
{
    if(m_server && m_server->isListening()){
        if(m_socket->isOpen()){
            m_socket->write(parameter.Array);
        }
    }
}


#include <QMessageBox>
void TcpServerForm::slot_listen()
{
    if(nullptr == this->m_server){
        m_server = new QTcpServer(this);
    }

    if(m_server->isListening()){
        QMessageBox msgBox;
        msgBox.setText("已经在监听中");
        msgBox.setInformativeText("提示");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
        msgBox.exec();

    }else{
        quint16 port = ui->lineEdit_local_port->text().toUInt();
        bool bl = m_server->listen(QHostAddress::Any, port);
        if(!bl){
            QString info = "监听本地端口"+QString::number(port)+"失败";
            QMessageBox msgBox;
            msgBox.setText(info);
            msgBox.setInformativeText("提示");
            msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
            msgBox.exec();

        }else{
            connect(m_server, &QTcpServer::newConnection, this, &TcpServerForm::slot_newconnection);
            QMessageBox msgBox;
            msgBox.setText("设备开始监听");
            msgBox.setInformativeText("提示");
            msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
            msgBox.exec();
        }
    }
}


#include <QTcpSocket>
void TcpServerForm::slot_newconnection()
{
    emit this->SigExtra("有客户端申请连接 ...");
    //获取最新连接的客户端套接字
    //[virtual] QTcpSocket *QTcpServer::nextPendingConnection()
    if(m_socket){
        if(m_socket->isOpen()){
            m_socket->close();
        }
        delete m_socket;m_socket=nullptr;
    }
    m_socket = m_server->nextPendingConnection();

    //此时，客户端就和服务器建立起来联系了
    //如果客户端有数据向服务器发送过来，那么该套接字就会自动发送一个readyread信号
    //我们可以将该信号连接到自定义的槽函数中处理相关逻辑
    if(m_socket){

        ui->lineEdit_client_ip->setText(m_socket->peerAddress().toString());
        ui->lineEdit_client_port->setText(QString::number(m_socket->peerPort()));

        QString info = "远程客户端IP-端口 : "+m_socket->peerAddress().toString()+ "-" + QString::number(m_socket->peerPort());
        emit this->SigExtra(info);

        connect(m_socket, &QTcpSocket::readyRead, this, &TcpServerForm::slot_readyRead);
    }
}

//关于readyRead信号对应槽函数的实现
void TcpServerForm::slot_readyRead()
{
    if(m_socket->bytesAvailable() != 0)
    {
        //读取当前客户端的相关数据
        //函数原型：QByteArray readAll();
        //功能：读取当前套接字中的所有数据，并返回一个字节数组
        //返回值：数据的字节数组
        QByteArray msg = m_socket->readAll();
        emit this->SigData(msg);
    }
}


void TcpServerForm::slot_disconnect()
{
    if(m_server && m_server->isListening()){
        if(m_socket){
            m_socket->close();delete m_socket;m_socket=nullptr;
        }
        m_server->close();
        QMessageBox msgBox;
        msgBox.setText("连接已断开");
        msgBox.setInformativeText("提示");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
        msgBox.exec();
    }
}
